/*
 * @features: 主要功能
 * @description: 内容说明
 * @Date: 2021-09-28 10:25:19
 * @Author: judu233(769471424@qq.com)
 * @LastEditTime: 2021-10-07 20:51:42
 * @LastEditors: judu233
 */

import c3d from "../../cc";
import ExtendsLoad from "../CCExtends";
import Random from "./Util/Random";
import RangeChack from "./Util/RangeCheck";

declare module "cc" {
    export namespace math {
        export namespace bits {
        }
        /**
         * 随时间变化进度值 
         * @param start 开始
         * @param end 结束
         * @param t 时间
         */
        export function progress(start: number, end: number, t: number): number;
        /**
        * 角度插值
        * @param current 
        * @param target 
        * @param t 
        */
        export function lerpAngle(current: number, target: number, t: number): number;

        /**
         * 取value的小数部分
         * @param value 
         */
        export function decimal(value: number): number;
    }
}

class MathExtends {
    static progress(start: number, end: number, t: number) {
        return start + (end - start) * t;
    }

    static lerpAngle(current: number, target: number, t: number) {
        current %= 360;
        target %= 360;

        var dAngle: number = target - current;
        if (dAngle > 180)
            target = current - (360 - dAngle);
        else if (dAngle < -180)
            target = current + (360 + dAngle);
        return (c3d.math.lerp(current, target, t) % 360 + 360) % 360;
    }

    static decimal(value: number) {
        return value - (Math.floor(value));
    }

    /**
     * 按一定的速度从一个角度转向令一个角度
     * @param current 
     * @param target 
     * @param speed 
     */
    public static angleTowards(current: number, target: number, speed: number): number {
        current %= 360;
        target %= 360;

        var dAngle: number = target - current;
        if (dAngle > 180)
            target = current - (360 - dAngle);
        else if (dAngle < -180)
            target = current + (360 + dAngle);

        var dir = target - current;
        if (speed > Math.abs(dir)) {
            return target;
        }
        return ((current + speed * Math.sign(dir)) % 360 + 360) % 360;
    }

    /**
     * 从 0 等分 space
     * 一般用于 for 找位置
     * @param {number} space 间距
     * @param {number} index 当前的索引
     * @param {number} length 最大的索引值
     * @returns {number}
     * @example
     * var a = Maths.zeroEqually(100, 0, 5); // -200
     * var a = Maths.zeroEqually(100, 1, 5); // -100
     * var a = Maths.zeroEqually(100, 2, 5); // 0
     * var a = Maths.zeroEqually(100, 3, 5); // 100
     * var a = Maths.zeroEqually(100, 4, 5); // 200
     */
    static zeroEqually(space: number, index: number, length: number): number {
        return (index - (length - 1) / 2) * space;
    }

    /**
     * 获取等分 min - max 后的平均点 ，不包括min,max
     * @param {number} [count=1] 等分几个
     * @param {number} min 
     * @param {number} max
     * @returns {number[]}
     * @example
     * var a = Maths.equally(1, 0, 10); //[5]
     * var b = Maths.equally(2, -10, 10); //[-5, 5]
     */
    static equally(count: number = 1, min: number, max: number): number[] {
        count++;
        let equally: number[] = [];
        let space = ((max - min) / count);
        for (let i = 1; i < count; i++) {
            equally.push(~~(min + space * i));
        }
        return equally;
    }
}

ExtendsLoad.load(c3d.math, MathExtends);

//额外扩展
c3d.math.check = new RangeChack();
c3d.math.randomMg = new Random();